/**
 * @file qq_ui.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_QQ != 0
/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_obj_t * qq_create_function_list(lv_obj_t * par);
static void qq_open_img_destroyed_timer_cb(lv_anim_t * anim);
static void qq_tileview_event_cb(lv_obj_t * tileview, lv_event_t e);
static void qq_leds_create(lv_obj_t * tileview);
static void qq_create_mine_info(void * src, char * nickname, char * qqid);
static void qq_validation_msg_event_cb(lv_obj_t * btn, lv_event_t event);
/**********************
 *  STATIC VARIABLES
 **********************/
static qq_get_friend_info_type getinfo_type;
char * my_access_token = NULL;
char * my_openid = NULL;
/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
#if QQ_UI_TEST
#define QQ_QRCODE_TEST  "R:/simulator/qr_test.png"
void qq_phone_confirm_timer_cb(void * param)
{
    qq_update_qrcode(WATCH_QQ_REG_OK, "", "");
}

void qq_scan_sucess_timer_cb(void * param)
{
    qq_update_qrcode(WATCH_QQ_SCANED_UNREG, "", "");
    Hal_Timer_Start(1000, qq_phone_confirm_timer_cb, NULL, false);
}

void qq_invalid_qrcode_timer_cb(void * param)
{
    qq_update_qrcode(WATCH_QQ_OTHER_FAIL, "", "");
}

void qq_show_qrcode_timer_cb(void * param)
{
    qq_show_qrcode(QQ_QRCODE_TEST);
    //qq_create_get_qr_failed();
    Hal_Timer_Start(1000, qq_scan_sucess_timer_cb, NULL, false);
    //Hal_Timer_Start(1000, qq_invalid_qrcode_timer_cb, NULL, false);
}

void qq_login_img_destroyed_timer_cb(void * param)
{
    qq_destroy_login();
    qq_create_main();
    //qq_show_login_failed();
}

watch_qq_user_info_t recent_info[] = {
    {"sfcxvxree", "werrrfere", "tree", NULL, 1635440581, 0, "416656990"},
    {"trfcvswwwre3124783984", "werrrfere", "nickname", "jack", 1635440000, 1, "21545663"},
};
lv_ll_t recent_info_ll;
void qq_get_recent_contact_timer_cb(void * param)
{
    _lv_ll_init(&recent_info_ll, sizeof(watch_qq_user_info_t));
    watch_qq_user_info_t * node;
    for(uint8_t i = 0; i < 2; i++) {
        node = (watch_qq_user_info_t *) _lv_ll_ins_tail(&recent_info_ll);
        memcpy(node, &recent_info[i], sizeof(watch_qq_user_info_t));
    }
    qq_create_recent_contacts_list(&recent_info_ll);
    //qq_no_msg_recently();
}

watch_qq_user_info_t friend_info[] = {
    {"123456789", "werrrfere", "tree", NULL, 1635440581, 0, "416656990"},
    {"142435255", "werrrfere", "nickname", "jack", 1635440000, 1, "21545663"},
    {"qrqr5436365", "werrrfere", "flower", NULL, 1635440581, 0, "31234435"},
    {"66457457457df", "werrrfere", "一棵树", NULL, 1635440000, 1, "112233445"},
    {"53543345dd", "werrrfere", "rick", "哥哥", 1635440581, 0, "3556677"},
    {"1414983589sdfsf", "werrrfere", "nickname", "大王", 1635440000, 1, "245664"},
    {"2352sdfsfdcaq2324qw", "werrrfere", "tree", "rick", 1635440581, 0, "7676454"},
    {"546346dfsrw", "werrrfere", "nickname", "morty", 1635440000, 1, "4166555323"},
};
lv_ll_t friend_info_ll;
void qq_get_friends_timer_cb(void * param)
{
    _lv_ll_init(&friend_info_ll, sizeof(watch_qq_user_info_t));
    watch_qq_user_info_t * node;
    uint8_t over = *(uint8_t *)param;
    if(over == 0) {
        for(uint8_t i = 0; i < 4; i++) {
            node = (watch_qq_user_info_t *) _lv_ll_ins_tail(&friend_info_ll);
            memcpy(node, &friend_info[i], sizeof(watch_qq_user_info_t));
        }
    } else {
        for(uint8_t i = 4; i < 8; i++) {
            node = (watch_qq_user_info_t *) _lv_ll_ins_tail(&friend_info_ll);
            memcpy(node, &friend_info[i], sizeof(watch_qq_user_info_t));
        }
    }
    watch_qq_get_friend_list_cnf_t friend = {
        WATCH_QQ_OK, 12323, over, 5, 4, friend_info_ll
    };
    qq_create_friends_list(&friend);
}

void qq_logging_out_timer_cb(void * param)
{
    qq_create_switch_account();
}

void qq_show_friend_info_timer_cb(void * param)
{
    watch_qq_user_info_t info = {"fafakgskdjgrnn", "werrrfere", "hahahah", NULL, 5657678, 0, "416656990"};
    qq_show_friend_info(&info);
}

void qq_find_friend_result_timer_cb(void * param)
{
    uint8_t res = *(uint8_t *)param;
    printf("res = %d\n", res);
    if(res)
        qq_get_friend_info(NULL);
    else
        qq_show_find_friend_failed();
}

void qq_add_friend_timer_cb(void * param)
{
    qq_add_friend_req_result(WATCH_QQ_OK);
}

void qq_get_friend_info_timer_cb(void * param)
{
    if(param != NULL)
        qq_friend_info_update_headimg(ICON_QQ_FRIENDS);
    else {
        watch_qq_user_info_t info = {
            "123456", "hdahfa", "一棵树", NULL, 1635440581, 1, "416656990",
        };
        qq_friend_info_update(&info);
    }
}

void qq_delete_friend_timer_cb(void * param)
{
    qq_del_friend_result(WATCH_QQ_OK);
}

watch_qq_validation_msg_t valid_msg[] = {
    {"1234567", "1234567", 0, 43834848, 1234, WATCH_QQ_SOURCE_FROM_QQ_ID, NULL},
    {"1234567", "1234567", 1, 3434355, 1234, WATCH_QQ_SOURCE_FROM_QQ_ID, NULL},
    {"1234567", "1234567", 2, 5656565, 1234, WATCH_QQ_SOURCE_FROM_QQ_ID, NULL},
    {"1234567", "1234567", 3, 353535, 1234, WATCH_QQ_SOURCE_FROM_QQ_ID, NULL},
    {"1234567", "1234567", 3, 45464646, 1234, WATCH_QQ_SOURCE_FROM_QQ_ID, NULL},
};

lv_ll_t msg_ll = {0};


void qq_get_validmsg_timer_cb(void * param)
{
    _lv_ll_init(&msg_ll, sizeof(watch_qq_validation_msg_t));
    watch_qq_validation_msg_t * node;
    for(uint8_t i = 0; i < 5; i++) {
        node = (watch_qq_validation_msg_t *) _lv_ll_ins_tail(&msg_ll);
        memcpy(node, &valid_msg[i], sizeof(watch_qq_validation_msg_t));
    }
    watch_qq_undecided_msg_successread_t msg = {
        5, 1, 5, msg_ll,
    };
    qq_create_validation_msg_list(&msg);
    _lv_ll_clear(&msg_ll);
}

void qq_validation_msg_detail_timer_cb(void * param)
{
    watch_qq_user_info_t info = {
        "123456", "hdahfa", "一棵树", NULL, 1635440581, 1, "416656990",
    };
    qq_validation_msg_detail_show(&info);
}

void qq_get_msg_timer_cb(void * param)
{
    qq_add_msg_into_list(NULL);
}

void qq_send_msg_timer_cb(void * param)
{
    hal_rtc_t time;
    Hal_Rtc_Gettime(&time);
    qq_send_msg_result(WATCH_QQ_OK, time_to_seconds(&time));
}

#endif

void qq_prepare_destory(lv_obj_t * activity_obj)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    qq_get_data_info_t * node = (qq_get_data_info_t *)_lv_ll_get_head(&ext->getdata_ll);
    while(node) {
        lv_mem_free(node->url);
        node = _lv_ll_get_next(&ext->getdata_ll, node);
    }
    _lv_ll_clear(&ext->getdata_ll);
    qq_stop_record(ext);
    qq_stop_play_voice(ext);
    watch_qq_reset_get_msg_flag();
#if QQ_UI_TEST == 0
    watch_qq_net_destroy();
#endif
    lv_img_cache_invalidate_src(NULL);
}

lv_obj_t * qq_create(lv_obj_t * activity_obj, uint8_t msg_type)
{
    lv_obj_t * obj;

    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_QQ_MAIN;
        activity_ext.create = NULL;//qq_create;
        activity_ext.prepare_destory =  qq_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) {
            return NULL;
        }
    }

    obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) {
        return NULL;
    }
    lv_watch_obj_set_anim_mode(obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
    lv_qq_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_qq_obj_ext_t));
    LV_ASSERT_MEM(ext);
    ext->leds_content = NULL;
    ext->qr_bg_cont = NULL;
    ext->friend = NULL;
    ext-> mine = NULL;
    ext->msg_list = NULL;
    ext->name = NULL;
    ext->friend_list = NULL;
    ext->login_state = 0;
    ext->friend_list_act_btn = NULL;
    ext->recent_list = NULL;
    ext->new_msg_type = msg_type;

    _lv_ll_init(&ext->getdata_ll, sizeof(qq_get_data_info_t));
    watch_qq_reset_get_msg_flag();

    lv_obj_t * img = lv_img_create(obj, NULL);
    lv_img_set_src(img, ICON_QQ_OPEN);
    ext->login = img;
    lv_anim_t a = {0};
    lv_anim_init(&a);
    lv_anim_set_var(&a, img);
    lv_anim_set_ready_cb(&a, (lv_anim_ready_cb_t)qq_open_img_destroyed_timer_cb);
    lv_anim_set_repeat_count(&a, 1);
    lv_anim_set_time(&a, 1000);
    lv_anim_start(&a);
    return obj;
}

void qq_new_msg_prepare_destory(lv_obj_t * activity_obj)
{
    lv_img_cache_invalidate_src(ICON_QQ_SMALL_ICON);
}

void qq_new_message_ignore_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    uint8_t num = lv_watch_get_free_num(btn);
    lv_obj_del(lv_watch_get_activity_obj(ACT_ID_QQ_NEW_MSG));
    if(watch_is_qq_activity() && num == QQ_NEW_FRIEND) {
        lv_qq_obj_ext_t * ext = qq_get_ext();
        if(ext->friend != NULL) {
            qq_validation_new_msg_tip();
        }
    }
}

void qq_new_message_check_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    uint8_t num = lv_watch_get_free_num(btn);
    lv_obj_del(lv_watch_get_activity_obj(ACT_ID_QQ_NEW_MSG));
    if(watch_is_qq_activity() && num == QQ_NEW_FRIEND) {
        lv_qq_obj_ext_t * ext = qq_get_ext();
        if(ext->friend != NULL) {
            lv_obj_t * tileview = lv_obj_get_child(qq_get_obj(), NULL);
            lv_tileview_ext_t * tileview_ext = lv_obj_get_ext_attr(tileview);
            if(ext->msg_list) {
                qq_stop_play_voice(ext);
            }
            if(tileview_ext->act_id.x != 1) {
                lv_tileview_set_tile_act(tileview, 1, 0, LV_ANIM_OFF);
            } else {
                if(lv_obj_count_children(ext->friend) > 1) {
                    lv_obj_t * child = lv_obj_get_child(ext->friend, NULL);
                    lv_obj_t * next_child = lv_obj_get_child(ext->friend, child);
                    while(next_child) {
                        lv_obj_del(child);
                        child = lv_obj_get_child(ext->friend, NULL);
                        next_child = lv_obj_get_child(ext->friend, child);
                    }
                }
                if(ext->friend_list) {
                    ext->friend_list = NULL;
                    ext->friend_list_act_btn = NULL;
                }
                if(ext->msg_list) {
                    ext->msg_list = NULL;
                    ext->name = NULL;
                }
            }
            lv_obj_t * scrl = lv_page_get_scrl(lv_obj_get_child_back(ext->friend, NULL));
            lv_obj_t * validmsg_btn = lv_obj_get_child_back(scrl, NULL);
            qq_validation_msg_event_cb(validmsg_btn, LV_EVENT_CLICKED);
        }
    } else {
#if QQ_UI_TEST == 0
        watch_qq_net_init();
#endif
        qq_create(NULL, num);
    }
}


lv_obj_t * qq_create_new_message(lv_obj_t * activity_obj, uint8_t msg_type)
{
    lv_obj_t * obj = lv_watch_get_activity_obj(ACT_ID_QQ_NEW_MSG);
    if(obj != NULL)
        return obj;

    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_QQ_NEW_MSG;
        activity_ext.create = NULL;
        activity_ext.prepare_destory = qq_new_msg_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) {
            return NULL;
        }
    }
    lv_obj_set_style_local_bg_opa(activity_obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_30);

    uint16_t txtId = 0;
    if(msg_type == 0)
        txtId = WATCH_TEXT_ID_QQ_NEW_MESSAGE;
    else
        txtId = WATCH_TEXT_ID_QQ_NEW_FRIEND;

    lv_obj_t * msg_cont = lv_cont_create(activity_obj, NULL);
    lv_obj_set_size(msg_cont, LV_HOR_RES * 5 / 6, LV_VER_RES * 2 / 5);
    lv_obj_align(msg_cont, activity_obj, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_local_bg_color(msg_cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_BG_GRAY);
    lv_obj_set_style_local_radius(msg_cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);

    lv_obj_t * img = lv_img_create(msg_cont, NULL);
    lv_img_set_src(img, ICON_QQ_SMALL_ICON);
    lv_obj_align(img, msg_cont, LV_ALIGN_IN_TOP_LEFT, 0, 0);
    lv_obj_t * label = lv_label_create(msg_cont, NULL);
    lv_label_set_text(label, "QQ");
    lv_obj_align(label, img, LV_ALIGN_OUT_RIGHT_MID, 0, 0);

    lv_obj_t * msg_label = lv_label_create(msg_cont, NULL);
    lv_label_set_text_id(msg_label, txtId);
    lv_obj_align(msg_label, msg_cont, LV_ALIGN_CENTER, 0, -lv_obj_get_height(msg_label) / 2);

    lv_obj_t * check_btn = lv_btn_create(msg_cont, NULL);
    lv_obj_set_size(check_btn, LV_HOR_RES / 3, LV_VER_RES / 7);
    lv_obj_set_style_local_bg_color(check_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_BLUE_NORMAL);
    lv_obj_set_style_local_bg_color(check_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, QQ_COLOR_BLUE_PRESSED);
    lv_obj_set_style_local_border_width(check_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_radius(check_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 50);
    lv_watch_set_free_num(check_btn, msg_type);
    lv_obj_set_event_cb(check_btn, qq_new_message_check_event_cb);
    lv_obj_t * check_label = lv_label_create(check_btn, NULL);
    lv_label_set_text_id(check_label, WATCH_TEXT_ID_QQ_CHECK);
    lv_obj_set_style_local_text_color(check_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    lv_obj_align(check_btn, msg_label, LV_ALIGN_OUT_BOTTOM_MID, -lv_obj_get_width(check_btn) * 2 / 3, lv_obj_get_height(check_btn) / 3);

    lv_obj_t * ignore_btn = lv_btn_create(msg_cont, check_btn);
    lv_obj_set_event_cb(ignore_btn, qq_new_message_ignore_event_cb);
    lv_obj_set_style_local_bg_color(ignore_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    lv_obj_set_style_local_bg_color(ignore_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_WHITE);
    lv_obj_set_style_local_border_width(ignore_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_watch_set_free_num(ignore_btn, msg_type);
    lv_obj_t * ignore_label = lv_label_create(ignore_btn, NULL);
    lv_label_set_text_id(ignore_label, WATCH_TEXT_ID_IGNORE);
    lv_obj_set_style_local_text_color(ignore_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_obj_align(ignore_btn, msg_label, LV_ALIGN_OUT_BOTTOM_MID, lv_obj_get_width(ignore_btn) * 2 / 3, lv_obj_get_height(ignore_btn) / 3);

    return activity_obj;
}

void qq_create_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;
    if(LV_EVENT_CLICKED == e) {
#if QQ_UI_TEST == 0
        watch_qq_net_init();
#endif
        lv_obj_t * obj = qq_create(NULL, QQ_NEW_MSG);
        LV_ASSERT_MEM(obj);
    }
}

lv_obj_t * qq_get_obj(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_QQ_MAIN);
    if(activity_obj == NULL) return NULL;

    lv_obj_t * watch_obj;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    return watch_obj;
}

lv_qq_obj_ext_t * qq_get_ext(void)
{
    lv_obj_t * watch_obj = qq_get_obj();
    if(watch_obj) {
        lv_qq_obj_ext_t * ext = lv_obj_get_ext_attr(watch_obj);
        return ext;
    }
    return NULL;
}

bool watch_is_qq_activity(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_QQ_MAIN);
    if(activity_obj)
        return true;
    else
        return false;
}

void qq_add_get_data_info(uint8_t type, uint8_t index, char * url)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    qq_get_data_info_t * node = (qq_get_data_info_t *)_lv_ll_ins_tail(&ext->getdata_ll);
    if(node) {
        node->data_type = type;
        node->index = index;
        node->url = lv_strdup(url);
    }
}

void qq_get_data_img_path(char * data, char * path, char * name)
{
    if(data == NULL || path == NULL)
        return;

    uint8_t header[8];
    for(uint8_t i = 0; i < 8; i++) {
        header[i] = data[i];
        printf("%s: header[%d]=%x\n", __FUNCTION__, i, header[i]);
    }

    uint8_t img_type = QQ_HEAD_TYPE_OTHER;
    if(header[0] == 0x89 &&
            header[1] == 0x50 &&
            header[2] == 0x4E &&
            header[3] == 0x47 &&
            header[4] == 0x0D &&
            header[5] == 0x0A &&
            header[6] == 0x1A &&
            header[7] == 0x0A)
        img_type = QQ_HEAD_TYPE_PNG;
    if(header[0] == 0xFF && header[1] == 0xD8)
        img_type = QQ_HEAD_TYPE_JPG;
    printf("%s:img type = %d\n", __FUNCTION__, img_type);

    if(img_type == QQ_HEAD_TYPE_OTHER) {
        snprintf(path, QQ_HEAD_PATH_LEN, "%s", ICON_QQ_DEF_HEAD);
    } else if(img_type == QQ_HEAD_TYPE_PNG) {
        snprintf(path, QQ_HEAD_PATH_LEN, "C:/%s.png", name);
    } else if(img_type == QQ_HEAD_TYPE_JPG) {
        snprintf(path, QQ_HEAD_PATH_LEN, "C:/%s.jpg", name);
    }
}

uint8_t qq_get_voice_duration(char * data, uint32_t data_size)
{
    uint8_t header = data[6];
    printf("%s: header=%x\n", __FUNCTION__, header);
    uint32_t frame_size;
    uint32_t per_sec_size;
    uint8_t duration;
    switch(header) {
        case 0x04:
            frame_size = 13;
            break;
        case 0x0C:
            frame_size = 14;
            break;
        case 0x14:
            frame_size = 16;
            break;
        case 0x1C:
            frame_size = 18;
            break;
        case 0x24:
            frame_size = 20;
            break;
        case 0x2C:
            frame_size = 21;
            break;
        case 0x34:
            frame_size = 27;
            break;
        case 0x3C:
            frame_size = 32;
            break;
        default:
            frame_size = 32;
            break;
    }
    per_sec_size = frame_size * 50;
    if(frame_size == 32)
        duration = (data_size - VOICE_MSG_AMR_HEAD_SIZE + (per_sec_size - 1)) / per_sec_size;
    else
        duration = (data_size - VOICE_MSG_AMR_HEAD_SIZE) / per_sec_size;
    return duration;
}

void qq_show_data(watch_qq_get_data_cnf_t * data)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    qq_get_data_info_t * node = (qq_get_data_info_t *)_lv_ll_get_tail(&ext->getdata_ll);
    lv_fs_file_t file;
    uint32_t rn;
    lv_fs_res_t res;
    while(node) {
        printf("%s: node->data_type = %d\n", __FUNCTION__, node->data_type);
        if(strncmp(node->url, data->url, strlen(node->url)) == 0) {
            if(node->data_type == QQ_DATA_QR) {
                if(data->result == WATCH_QQ_OK) {
                    res = lv_fs_open(&file, QQ_QR_PATH, LV_FS_MODE_WR);
                    if(res == LV_FS_RES_OK) {
                        res = lv_fs_write(&file, (void *)data->data, data->datalen, &rn);
                        lv_fs_close(&file);
                    }
                    printf("%s:write qr_code file OK!\n", __FUNCTION__);
                    qq_show_qrcode(QQ_QR_PATH);
                } else
                    qq_create_get_qr_failed();
            } else if(node->data_type == QQ_DATA_MY_HEAD) {
                if(data->result == WATCH_QQ_OK) {
                    char path[QQ_HEAD_PATH_LEN];
                    watch_qq_login_info_t * info = watch_qq_get_last_login_info();
                    qq_get_data_img_path(data->data, path, info->qqid);
                    res = lv_fs_open(&file, path, LV_FS_MODE_WR);
                    if(res == LV_FS_RES_OK) {
                        res = lv_fs_write(&file, (void *)data->data, data->datalen, &rn);
                        lv_fs_close(&file);
                    }
                    printf("%s:write my head file path = %s OK!\n", __FUNCTION__, path);
                    if(ext->mine) {
                        lv_obj_t * head_img = lv_obj_get_child_back(ext->mine, NULL);
                        lv_img_set_src(head_img, path);
                    }
                    watch_qq_save_my_head_path(info->qqid, path);
                    lv_mem_free(info);
                }
            } else if(node->data_type == QQ_DATA_FRIEND_HEAD) {
                if(data->result == WATCH_QQ_OK) {
                    qq_friend_btn_ext_t * btn_ext = lv_obj_get_ext_attr(ext->friend_list_act_btn);
                    char path[QQ_HEAD_PATH_LEN];
                    qq_get_data_img_path(data->data, path, btn_ext->info.qqid);
                    res = lv_fs_open(&file, path, LV_FS_MODE_WR);
                    if(res == LV_FS_RES_OK) {
                        res = lv_fs_write(&file, (void *)data->data, data->datalen, &rn);
                        lv_fs_close(&file);
                    }
                    printf("%s:write friend head file %s OK!\n", __FUNCTION__, path);
                    qq_friend_info_update_headimg(path);
                }
            } else if(node->data_type == QQ_DATA_MSG_VOICE) {
                if(data->result == WATCH_QQ_OK) {
                    if(ext->msg_list == NULL || ext->name == NULL) break;
                    lv_obj_t * scrl = lv_obj_get_child(ext->msg_list, NULL);
                    lv_obj_t * list_obj = lv_obj_get_child(scrl, NULL);
                    while(list_obj) {
                        uint32_t free_num = lv_watch_get_free_num(list_obj);
                        uint8_t msgtype = QQ_MSG_GET_MSG_TYPE(free_num);
                        if(!qq_list_obj_is_label(list_obj) && msgtype == QQ_MSG_TYPE_VOICE) {
                            qq_msg_voice_obj_ext_t * voice_ext = lv_obj_get_ext_attr(list_obj);
                            if(!strncmp(data->url, voice_ext->url, strlen(data->url))) {
                                voice_ext->voice_buffer = lv_mem_alloc(data->datalen + 1);
                                memcpy(voice_ext->voice_buffer, data->data, data->datalen);
                                voice_ext->voice_size = data->datalen;
                                printf("%s: size = %d\n", __FUNCTION__, voice_ext->voice_size);
                                lv_watch_set_free_num(list_obj, QQ_MSG_CLEAR_UNLOAD_FLAG(free_num));
                                break;
                            }
                        }
                        list_obj = lv_obj_get_child(scrl, list_obj);
                    }
                    qq_msg_list_ext_t * list_ext = (qq_msg_list_ext_t *)lv_obj_get_ext_attr(ext->msg_list);
                    qq_play_voice(lv_obj_get_child(list_obj, NULL), list_ext);
                }
            } else if(node->data_type == QQ_DATA_MSG_PIC) {
            } else if(node->data_type == QQ_DATA_VALID_FRIEND_HEAD) {
                if(data->result == WATCH_QQ_OK) {
                    char path[QQ_HEAD_PATH_LEN];
                    qq_validmsg_btn_ext_t * btn_ext = lv_obj_get_ext_attr(ext->friend_list_act_btn);
                    qq_get_data_img_path(data->data, path, btn_ext->qqid);
                    res = lv_fs_open(&file, path, LV_FS_MODE_WR);
                    if(res == LV_FS_RES_OK) {
                        res = lv_fs_write(&file, (void *)data->data, data->datalen, &rn);
                        lv_fs_close(&file);
                    }
                    printf("%s:write friend head file %s OK!\n", __FUNCTION__, path);
                    qq_validation_msg_detail_update_headimg(path);
                }
            }
            lv_mem_free(node->url);
            _lv_ll_remove(&ext->getdata_ll, node);
            lv_mem_free(node);
            break;
        }
        node = _lv_ll_get_prev(&ext->getdata_ll, node);
    }
}

void qq_create_main(void)
{
    static lv_point_t valid_pos[] = {
        {0, 0}, {1, 0}, {2, 0}
    };

    lv_obj_t * par = qq_get_obj();
    lv_obj_t * tileview = lv_tileview_create(par, NULL);
    lv_tileview_set_valid_positions(tileview, valid_pos, 3);
    lv_tileview_set_edge_flash(tileview, true);
    lv_tileview_set_anim_time(tileview, 60);
    lv_page_set_scrollbar_mode(tileview, LV_SCROLLBAR_MODE_OFF);
    lv_page_set_edge_flash(tileview, false);
    lv_obj_set_event_cb(tileview, qq_tileview_event_cb);

    lv_qq_obj_ext_t * ext = qq_get_ext();
    ext->recentmsg = qq_tileview_add_tile(tileview, 0);
    ext->friend = qq_tileview_add_tile(tileview, 1);
    ext->mine = qq_tileview_add_tile(tileview, 2);
    lv_tileview_set_tile_act(tileview, 0, 0, LV_ANIM_OFF);

    lv_obj_t * img = lv_img_create(ext->recentmsg, NULL);
    lv_img_set_src(img, ICON_QQ_MSG);
    lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, -LV_VER_RES / 10);

    lv_obj_t * label = lv_label_create(ext->recentmsg, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_QQ_GET_RECENT_CONTACTS);
    lv_obj_align(label, img, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_VER_RES / 8);
    lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);

#if QQ_UI_TEST
    Hal_Timer_Start(1000, qq_get_recent_contact_timer_cb, NULL, false);
#else
    qq_init_contact_list();
    qq_get_msg();
#endif
    qq_create_function_list(ext->friend);
    if(ext->new_msg_type == QQ_NEW_FRIEND) {
        lv_tileview_set_tile_act(tileview, 1, 0, LV_ANIM_OFF);
        qq_validation_new_msg_tip();
    }

#if QQ_UI_TEST
    qq_create_mine_info(ICON_QQ_DEF_HEAD, "tree", "416656990");
#else
    watch_qq_login_info_t * info = watch_qq_get_last_login_info();
    if(info != NULL) {
        printf("%s: path:%s name:%s, qq:%s\n", __FUNCTION__, info->head_path, info->nickname, info->qqid);
        if(my_openid == NULL) {
            qq_create_mine_info(info->head_path, info->nickname, info->qqid);
        } else {
            if(!strncmp(info->openid, my_openid, 64)) {
                qq_create_mine_info(info->head_path, info->nickname, info->qqid);
                lv_mem_free(my_openid);
                my_openid = NULL;
            } else {
                printf("%s: not logging in ID, requst my info\n", __FUNCTION__);
                watch_qq_get_friend_info_req_t * get_friend = (watch_qq_get_friend_info_req_t *)lv_mem_alloc(sizeof(watch_qq_get_friend_info_req_t));
                memset(get_friend, 0, sizeof(watch_qq_get_friend_info_req_t));
                memcpy(get_friend->openid, my_openid, 64);
                lv_mem_free(my_openid);
                my_openid = NULL;
                qq_set_get_friend_info_type(QQ_GET_MY_INFO);
                watch_qq_get_friend_info_req(get_friend);
            }
        }
        lv_mem_free(info);
    } else {
        //my info req
        printf("%s: no loginfo, requst my info\n", __FUNCTION__);
        watch_qq_get_friend_info_req_t * get_friend = (watch_qq_get_friend_info_req_t *)lv_mem_alloc(sizeof(watch_qq_get_friend_info_req_t));
        memset(get_friend, 0, sizeof(watch_qq_get_friend_info_req_t));
        memcpy(get_friend->openid, my_openid, 64);
        lv_mem_free(my_openid);
        my_openid = NULL;
        qq_set_get_friend_info_type(QQ_GET_MY_INFO);
        watch_qq_get_friend_info_req(get_friend);
    }
#endif
    qq_leds_create(tileview);
}

void qq_back_img_event_cb(lv_obj_t * img, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    uint8_t num = lv_watch_get_free_num(img);
    printf("%s: num = %d\n", __FUNCTION__, num);
    lv_qq_obj_ext_t * ext = qq_get_ext();
    lv_obj_t * par = lv_obj_get_parent(img);
    if(num == QQ_QRCODE) {
        lv_obj_del(ext->qr_bg_cont);
        ext->qr_bg_cont = NULL;
    } else if(num == QQ_FRIEND_LIST || num == QQ_VALID_MSG) {
        lv_obj_del(par);
        lv_obj_set_hidden(ext->leds_content, false);
        ext->friend_list = NULL;
        ext->friend_list_act_btn = NULL;
    } else if(num == QQ_INPUT_NUM) {
        lv_obj_del(lv_obj_get_parent(lv_obj_get_parent(par)));
        lv_obj_set_hidden(ext->leds_content, false);
    } else if(num == QQ_CHAT) {
        qq_msg_list_ext_t * list_ext = lv_obj_get_ext_attr(ext->msg_list);
        if(list_ext->getting_msg) return;
        lv_obj_t * tileview = lv_obj_get_child(qq_get_obj(), NULL);
        lv_tileview_ext_t * tile_ext = lv_obj_get_ext_attr(tileview);
        printf("%s: x = %d\n", __FUNCTION__, tile_ext->act_id.x);
        qq_stop_play_voice(ext);
        if(tile_ext->act_id.x == 0)
            lv_obj_set_hidden(ext->leds_content, false);
        lv_obj_del(par);
        ext->msg_list = NULL;
        ext->name = NULL;
        qq_get_recent_contact();
    } else if(num == QQ_FRIEND_INFO) {
        lv_obj_del(par);
        qq_friend_list_update_img_head();
    } else {
        lv_obj_del(par);
    }
}

lv_obj_t * qq_create_back_img(lv_obj_t * par, qq_back_img_type type)
{
    lv_obj_t * back_img = lv_img_create(par, NULL);
    lv_img_set_src(back_img, ICON_QQ_BACK);
    lv_obj_align(back_img, par, LV_ALIGN_IN_TOP_LEFT, QQ_BACK_IMG_PAD_LEFT, QQ_PAD_VER);
    lv_watch_set_free_num(back_img, type);
    lv_obj_set_click(back_img, true);
    lv_obj_set_event_cb(back_img, qq_back_img_event_cb);
    return back_img;
}

lv_obj_t * qq_list_add(lv_obj_t * list, void * img_src, char * text, void * param, qq_list_type type)
{
    char str[16] = {0};
    static uint16_t btn_size = 0;
    btn_size ++;
    /*Create a list element with the image an the text*/
    lv_obj_t * btn;
    btn = lv_btn_create(list, NULL);

    /*Save the original signal function because it will be required in `lv_list_btn_signal`*/
    lv_list_set_ancestor_btn_signal(btn);

    /*Set the default styles*/
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_BG_GRAY);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN,  LV_STATE_DEFAULT, 50);
    lv_obj_set_style_local_pad_left(btn,  LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_set_style_local_pad_right(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_set_style_local_pad_top(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_bottom(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_inner(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 10);
    lv_obj_set_style_local_line_width(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, QQ_COLOR_BG_GRAY);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN,  LV_STATE_PRESSED, 50);
    lv_obj_set_style_local_pad_left(btn,  LV_BTN_PART_MAIN, LV_STATE_PRESSED, 5);
    lv_obj_set_style_local_pad_right(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 5);
    lv_obj_set_style_local_pad_top(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 0);
    lv_obj_set_style_local_pad_bottom(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 0);
    lv_obj_set_style_local_pad_inner(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 10);
    lv_obj_set_style_local_line_width(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 0);

    lv_page_glue_obj(btn, true);
    lv_obj_add_protect(btn, LV_PROTECT_PRESS_LOST);
    lv_obj_set_signal_cb(btn, lv_list_get_listbtn_signal());

    /*Make the size adjustment*/
    lv_coord_t w = lv_obj_get_width(list);
    uint16_t pad_w = w - lv_obj_get_style_pad_left(list, LV_LIST_PART_SCROLLABLE);
    lv_obj_set_size(btn, pad_w, (LV_VER_RES - QQ_PAD_VER * 2) / 5);
    lv_btn_set_layout(btn, LV_LAYOUT_OFF);

    /*portrait*/
    lv_obj_t * img = lv_img_create(btn, NULL);
    lv_obj_set_style_local_radius(img, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
    lv_img_set_src(img, img_src);
    lv_obj_set_click(img, false);
    lv_obj_align(img, btn, LV_ALIGN_IN_LEFT_MID, 5, 0);


    if(type == LIST_TYPE_RECENT_CONTACTS) {
        /*name*/
        lv_obj_t * cont = lv_cont_create(btn, NULL);
        lv_obj_set_style_local_bg_opa(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
        lv_obj_set_click(cont, false);
        lv_cont_set_fit2(cont, LV_FIT_TIGHT, LV_FIT_TIGHT);
        lv_obj_set_style_local_pad_top(cont, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
        lv_obj_set_style_local_pad_inner(cont, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
        if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL)
            lv_cont_set_layout(cont, LV_LAYOUT_COLUMN_RIGHT);
        else
            lv_cont_set_layout(cont, LV_LAYOUT_COLUMN_LEFT);

        lv_obj_t * label_name = lv_label_create(cont, NULL);
        lv_label_set_text(label_name, text);
        lv_obj_set_style_local_text_color(label_name, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_TEXT_LIGHT);
        lv_obj_set_click(label_name, false);
        lv_label_set_long_mode(label_name, LV_LABEL_LONG_DOT);
        lv_obj_set_width(label_name, lv_obj_get_width(btn) - lv_obj_get_width(img)
                         - lv_obj_get_style_pad_inner(btn, LV_STATE_DEFAULT)
                         - lv_obj_get_style_pad_left(btn, LV_STATE_DEFAULT)
                         - lv_obj_get_style_pad_right(btn, LV_STATE_DEFAULT));
        /*time*/
        lv_obj_t * label_time = lv_label_create(cont, NULL);
        printf("%s: time = %s\n", __FUNCTION__, (char *)param);
        lv_label_set_text(label_time, (char *)param);
        lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
        lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_16);
        lv_obj_set_click(label_time, false);
        lv_obj_align(cont, img, LV_ALIGN_OUT_RIGHT_MID, 10, 0);

    } else if(type == LIST_TYPE_FUNCTION) {
        lv_obj_t * label_func = lv_label_create(btn, NULL);
        lv_obj_set_style_local_text_color(label_func, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_TEXT_LIGHT);
        lv_label_set_text(label_func, text);
        lv_obj_set_click(label_func, false);
        lv_obj_align(label_func, img, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
    } else if(type == LIST_TYPE_MY_FRIENDS) {
        lv_btn_set_layout(btn, LV_LAYOUT_ROW_MID);
        lv_obj_t * label_name = lv_label_create(btn, NULL);
        lv_obj_set_style_local_text_color(label_name, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_TEXT_LIGHT);
        lv_label_set_text(label_name, text);
        lv_label_set_long_mode(label_name, LV_LABEL_LONG_DOT);
        lv_obj_set_width(label_name, lv_obj_get_width(btn) - lv_obj_get_width(img)
                         - lv_obj_get_style_pad_inner(btn, LV_STATE_DEFAULT)
                         - lv_obj_get_style_pad_left(btn, LV_STATE_DEFAULT)
                         - lv_obj_get_style_pad_right(btn, LV_STATE_DEFAULT));
        lv_obj_set_click(label_name, false);
    }  else if(type == LIST_TYPE_VALIDATION_MSG) {
        lv_btn_set_layout(btn, LV_LAYOUT_OFF);
        watch_qq_validation_msg_t * msg = (watch_qq_validation_msg_t *)param;
        lv_obj_t * cont = lv_cont_create(btn, NULL);
        lv_obj_set_style_local_bg_opa(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
        lv_obj_set_click(cont, false);
        lv_cont_set_fit2(cont, LV_FIT_TIGHT, LV_FIT_TIGHT);
        lv_obj_set_style_local_pad_top(cont, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
        lv_obj_set_style_local_pad_inner(cont, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
        if(lv_obj_get_base_dir(btn) == LV_BIDI_DIR_RTL)
            lv_cont_set_layout(cont, LV_LAYOUT_COLUMN_RIGHT);
        else
            lv_cont_set_layout(cont, LV_LAYOUT_COLUMN_LEFT);

        lv_obj_t * label_msg = lv_label_create(cont, NULL);
        uint16_t txtId = qq_get_txtId_from_reqtype(msg->reqtype);
        if(msg->reqtype == WATCH_QQ_UNDECIDED_REQTYPE_WAITING_FRIEND_VERIFY)
            txtId = WATCH_TEXT_ID_QQ_WAITING_VERIFY;;
        lv_label_set_text_id(label_msg, txtId);
        lv_obj_set_style_local_text_color(label_msg, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
        lv_obj_set_click(label_msg, false);

        /*time*/
        hal_rtc_t time;
#if QQ_UI_TEST
        Hal_Rtc_Gettime(&time);
#else
        seconds_to_time(msg->timestamp, &time);
#endif
        memset(str, 0, 16);
        snprintf(str, 16, "%d-%02d-%02d", time.tm_year, time.tm_mon, time.tm_mday);
        lv_obj_t * label_time = lv_label_create(cont, NULL);
        lv_label_set_text(label_time, str);
        lv_obj_set_style_local_text_color(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
        lv_obj_set_style_local_text_font(label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_14);
        lv_obj_set_click(label_time, false);
        lv_obj_align(cont, img, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
    }
    return btn;
}

lv_obj_t * qq_create_list(lv_obj_t * par)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    lv_obj_t * list = lv_list_create(par, NULL);
    lv_obj_set_size(list, LV_HOR_RES - QQ_PAD_HOR * 2, LV_VER_RES - lv_obj_get_height(ext->leds_content) - QQ_PAD_VER * 2);
    lv_obj_set_pos(list, QQ_PAD_HOR, lv_obj_get_height(ext->leds_content) + QQ_PAD_VER);
    lv_page_set_edge_flash(list, false);
    lv_page_set_scrollbar_mode(list, LV_SCROLLBAR_MODE_OFF);
    lv_obj_set_style_local_bg_opa(list, LV_LIST_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_set_style_local_bg_opa(list, LV_LIST_PART_SCROLLABLE, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_set_style_local_pad_inner(list, LV_LIST_PART_SCROLLABLE, LV_STATE_DEFAULT, 5);
    lv_obj_set_style_local_pad_left(list, LV_LIST_PART_SCROLLABLE, LV_STATE_DEFAULT, 5);
    lv_obj_set_style_local_pad_right(list, LV_LIST_PART_SCROLLABLE, LV_STATE_DEFAULT, 5);
    return list;
}

lv_obj_t * qq_create_bg_cont(lv_obj_t * par, lv_opa_t opa, uint16_t txtId)
{
    lv_obj_t * cont = lv_cont_create(par, NULL);
    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
    if(opa != LV_OPA_COVER)
        lv_obj_set_style_local_bg_opa(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, opa);
    else
        lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_obj_set_click(cont, true);
    if(txtId != 0) {
        lv_obj_t * label = lv_label_create(cont, NULL);
        lv_label_set_text_id(label, txtId);
        lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
        lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    }
    return cont;
}

lv_obj_t * qq_create_msgbox(lv_obj_t * par, uint16_t txtId, lv_event_cb_t cb)
{
    static const char * txt[3];
    txt[0] = (char *)lv_lang_get_text(WATCH_TEXT_ID_OK);
    txt[1] = (char *)lv_lang_get_text(WATCH_TEXT_ID_CANCEL);
    txt[2] = "";
    lv_obj_t * cont = qq_create_bg_cont(par, LV_OPA_70, 0);
    lv_obj_t * msgbox = lv_msgbox_create(cont, NULL);
    lv_msgbox_set_text(msgbox, (char *)lv_lang_get_text(txtId));
    lv_msgbox_add_btns(msgbox, txt);
    lv_obj_set_size(msgbox, LV_HOR_RES * 5 / 6, LV_VER_RES * 3 / 4);
    lv_obj_set_event_cb(lv_msgbox_get_btnmatrix(msgbox), cb);
    lv_obj_align(msgbox, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_local_bg_color(msgbox, LV_MSGBOX_PART_BG, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_obj_set_style_local_bg_color(lv_msgbox_get_btnmatrix(msgbox), LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    return msgbox;
}

void qq_set_get_friend_info_type(uint8_t type)
{
    getinfo_type = type;
}

void qq_update_friend_info(watch_qq_user_info_t * info)
{
    if(getinfo_type == QQ_GET_MY_INFO) {
        printf("%s:update my_info\n", __FUNCTION__);
        qq_create_mine_info(ICON_QQ_DEF_HEAD, info->nickname, info->qqid);

        watch_qq_login_info_t log_info;
        memset(&log_info, 0, sizeof(watch_qq_login_info_t));
        memcpy(log_info.qqid, info->qqid, QQ_ID_LEN);
        memcpy(log_info.openid, info->openid, 64);
        memcpy(log_info.access_token, my_access_token, 64);
        lv_mem_free(my_access_token);
        my_access_token = NULL;
        memcpy(log_info.nickname, info->nickname, 128);
        hal_rtc_t time;
        Hal_Rtc_Gettime(&time);
        log_info.login_time = time_to_seconds(&time);
        watch_qq_save_login_info(&log_info);
#if QQ_UI_TEST == 0
        watch_qq_get_data_req_t * get_data_req = lv_mem_alloc(sizeof(watch_qq_get_data_req));
        get_data_req->url = lv_strdup(info->headurl);
        qq_add_get_data_info(QQ_DATA_MY_HEAD, 0, get_data_req->url);
        watch_qq_get_data_req(get_data_req);
#endif
    } else if(getinfo_type == QQ_FIND_FRIEND_INFO) {
        qq_show_friend_info(info);
    } else if(getinfo_type == QQ_GET_VALIDMSG_INFO) {
        qq_validation_msg_detail_show(info);
    } else if(getinfo_type == QQ_GET_LIST_FRIEND_INFO) {
        qq_friend_info_update(info);
    }
}

void qq_get_timestr_from_timestamp(uint32_t timestamp, char * timestr, uint8_t len)
{
    if(timestr == NULL) return;

    hal_rtc_t time;
    hal_rtc_t time_now;
    uint32_t time_utc8 = timestamp + (8 * 3600);
    seconds_to_time(time_utc8, &time);
    Hal_Rtc_Gettime(&time_now);
    //printf("%s: time now is %d-%02d-%02d %02d:%02d:%02d week%d\n", __FUNCTION__,
    //       time_now.tm_year, time_now.tm_mon, time_now.tm_mday, time_now.tm_hour, time_now.tm_min, time_now.tm_sec, time_now.tm_wday);
    if(time.tm_mday != time_now.tm_mday) {
        snprintf(timestr, len, "%s", (char *)lv_lang_get_text(WATCH_TEXT_ID_YESTERDAY));
    } else {
        if(time.tm_hour == time_now.tm_hour) {
            if(time.tm_min == time_now.tm_min)
                snprintf(timestr, len, "%s", (char *)lv_lang_get_text(WATCH_TEXT_ID_QQ_JUST));
            else
                snprintf(timestr, len, "%d%s", time_now.tm_min - time.tm_min, (char *)lv_lang_get_text(WATCH_TEXT_ID_QQ_MINS_AGO));
        } else {
            if(time.tm_hour > 12)
                snprintf(timestr, len, "%s %02d:%02d", (char *)lv_lang_get_text(WATCH_TEXT_ID_PM), time.tm_hour, time.tm_min);
            else
                snprintf(timestr, len, "%s %02d:%02d", (char *)lv_lang_get_text(WATCH_TEXT_ID_AM), time.tm_hour, time.tm_min);
        }
    }
}
/**********************
 *   STATIC FUNCTIONS
 **********************/
static void qq_open_img_destroyed_timer_cb(lv_anim_t * anim)
{
    lv_obj_t * obj = qq_get_obj();
    if(obj == NULL) return;
    if((false == watch_modem_sim_present_check_req())
            || (MMI_MODEM_SIGNAL_BAR_0 == watch_modem_get_signal_bar_req())) {
        qq_create_no_network(obj);
        return;
    }
    watch_qq_login_info_t * login_info = watch_qq_get_last_login_info();

    if(login_info != NULL) {
#if QQ_UI_TEST == 0
        watch_qq_register_with_openid_req_t * reg_req =
            (watch_qq_register_with_openid_req_t *)lv_mem_alloc(sizeof(watch_qq_register_with_openid_req_t));
        memcpy(reg_req->openid, login_info->openid, 64);
        memcpy(reg_req->access_token, login_info->access_token, 64);
        reg_req->state = 0;
        watch_qq_register_with_openid_req(reg_req);
#endif
        lv_mem_free(login_info);
        qq_show_login();
    } else {
        qq_create_scan_login();
    }
}

lv_obj_t * qq_tileview_add_tile(lv_obj_t * tileview, uint16_t id)
{
    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
    lv_obj_t * cont = lv_cont_create(tileview, NULL);
    lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_x(cont, LV_HOR_RES * ext->valid_pos[id].x);
    lv_tileview_add_element(tileview, cont);
    lv_obj_set_click(cont, false);
    return cont;
}

static void qq_leds_create(lv_obj_t * tileview)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    lv_tileview_ext_t * tile_ext = lv_obj_get_ext_attr(tileview);
    lv_obj_t * led1;
    lv_obj_t * led2;
    lv_obj_t * led3;
    if(NULL == ext->leds_content) {
        ext->leds_content = lv_cont_create(tileview, NULL);
        lv_obj_set_base_dir(ext->leds_content, LV_BIDI_DIR_LTR);
        lv_cont_set_fit(ext->leds_content, LV_FIT_TIGHT);
        lv_cont_set_layout(ext->leds_content, LV_LAYOUT_ROW_MID);
        lv_obj_set_style_local_bg_opa(ext->leds_content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
        lv_obj_set_style_local_pad_inner(ext->leds_content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_DPI / 12);
        lv_obj_set_click(ext->leds_content, false);
        led1 = lv_img_create(ext->leds_content, NULL);
        led2 = lv_img_create(ext->leds_content, NULL);
        led3 = lv_img_create(ext->leds_content, NULL);
    } else {
        led1 = lv_obj_get_child_back(ext->leds_content, NULL);
        led2 = lv_obj_get_child_back(ext->leds_content, led1);
        led3 = lv_obj_get_child(ext->leds_content, NULL);
    }

    if(tile_ext->act_id.x == 0) {
        lv_img_set_src(led1, ICON_QQ_MSG_SMALL);
        lv_img_set_src(led2, ICON_QQ_LED_WHITE);
        lv_img_set_src(led3, ICON_QQ_LED_WHITE);
    } else if(tile_ext->act_id.x == 1) {
        lv_img_set_src(led1, ICON_QQ_LED_WHITE);
        lv_img_set_src(led2, ICON_QQ_FRIEND_SMALL);
        lv_img_set_src(led3, ICON_QQ_LED_WHITE);
    } else {
        lv_img_set_src(led1, ICON_QQ_LED_WHITE);
        lv_img_set_src(led2, ICON_QQ_LED_WHITE);
        lv_img_set_src(led3, ICON_QQ_SMALL);
    }

    lv_obj_set_pos(ext->leds_content, (LV_HOR_RES - lv_obj_get_width(ext->leds_content)) / 2 + LV_HOR_RES * tile_ext->act_id.x, 0);
}

static void qq_tileview_event_cb(lv_obj_t * tileview, lv_event_t e)
{
    if(LV_EVENT_VALUE_CHANGED == e) {
        qq_leds_create(tileview);
    }
}

static void qq_create_mine_info(void * src, char * nickname, char * qqid)
{
    lv_qq_obj_ext_t * ext = qq_get_ext();
    lv_obj_t * par = ext->mine;
    if(lv_obj_count_children(par) > 0) {
        printf("%s: mine info has been created already!\n", __FUNCTION__);
        return;
    }
    lv_obj_t * head_img = lv_img_create(par, NULL);
    lv_img_set_src(head_img, src);
    lv_obj_align(head_img, NULL, LV_ALIGN_IN_TOP_MID, 0, LV_VER_RES / 6 + QQ_PAD_VER);

    lv_obj_t * name_label = lv_label_create(par, NULL);
    lv_label_set_text(name_label, nickname);
    lv_label_set_long_mode(name_label, LV_LABEL_LONG_DOT);
    lv_obj_set_width(name_label, LV_HOR_RES * 2 / 3);
    lv_label_set_align(name_label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(name_label, head_img, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_VER_RES / 20);

    lv_obj_t * num_label = lv_label_create(par, NULL);
    lv_label_set_text(num_label, qqid);
    lv_obj_align(num_label, name_label, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_VER_RES / 20);

    lv_obj_t * btn = lv_btn_create(par, NULL);
    lv_obj_set_size(btn, LV_HOR_RES * 5 / 6 - QQ_PAD_HOR * 2, LV_VER_RES / 5 - QQ_PAD_VER);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, QQ_COLOR_RED_NORMAL);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, QQ_COLOR_RED_PRESSED);
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 50);
    lv_obj_set_event_cb(btn, qq_logout_btn_event_cb);
    lv_obj_t * label = lv_label_create(btn, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_QQ_LOG_OUT);
    lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
    lv_obj_align(btn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -LV_VER_RES / 20 - QQ_PAD_VER * 2);
}

static void qq_validation_msg_event_cb(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    if(lv_obj_count_children(btn) == 3)
        lv_obj_del(lv_obj_get_child(btn, NULL));
    lv_qq_obj_ext_t * ext = qq_get_ext();
    qq_create_bg_cont(ext->friend, LV_OPA_90, WATCH_TEXT_ID_QQ_PULLING_DATA);

#if QQ_UI_TEST
    Hal_Timer_Start(1000, qq_get_validmsg_timer_cb, NULL, false);
#else
    watch_qq_get_undecided_req_t * undecided_req = lv_mem_alloc(sizeof(watch_qq_get_undecided_req_t));
    undecided_req->validation_seq = 0;
    undecided_req->query_type = WATCH_QQ_QUERY_TYPE_ALL;
    undecided_req->start_index = 0;
    undecided_req->reqnum = MMI_QQ_GET_VALID_MSG_CNT;
    watch_qq_login_info_t * info = watch_qq_get_last_login_info();
    memcpy(undecided_req->from_openid, info->openid, 64);
    watch_qq_get_undecided_req(undecided_req);
    lv_mem_free(info);
#endif
}

static void qq_add_friend_event_cb(lv_obj_t * obj, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    qq_create_add_friend();
}

static void qq_my_friends_event_cb(lv_obj_t * obj, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    qq_get_my_friend_list();
}

static lv_obj_t * qq_create_function_list(lv_obj_t * par)
{
    lv_obj_t * list = qq_create_list(par);
    lv_obj_t * tileview = lv_obj_get_parent(par);
    lv_tileview_add_element(tileview, list);
    lv_tileview_add_element(tileview, lv_page_get_scrl(list));
    lv_obj_t * btn;
    btn = qq_list_add(list,  ICON_QQ_VALID_MSG, (char *)lv_lang_get_text(WATCH_TEXT_ID_QQ_VALIDATION_MSG), NULL, LIST_TYPE_FUNCTION);
    lv_obj_set_event_cb(btn,  qq_validation_msg_event_cb);
    btn = qq_list_add(list,  ICON_QQ_ADD_FRIEND, (char *)lv_lang_get_text(WATCH_TEXT_ID_QQ_ADD_FRIEND), NULL, LIST_TYPE_FUNCTION);
    lv_obj_set_event_cb(btn, qq_add_friend_event_cb);
    btn = qq_list_add(list,  ICON_QQ_FRIENDS, (char *)lv_lang_get_text(WATCH_TEXT_ID_QQ_FRIENDS), NULL, LIST_TYPE_FUNCTION);
    lv_obj_set_event_cb(btn, qq_my_friends_event_cb);
    return list;
}
#endif /*USE_LV_WATCH_QQ*/
